home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Video
/
World of Video.iso
/
gfxprograms
/
viewers
/
edushow
/
edushow.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-13
|
16KB
|
624 lines
/*********************************************************************
* EDUSHOW Copyright 1990 Laurence Vanhelsuwé
* -------
* Specialised interactive slideshow program for educational purposes
* or giving presentations to groups of people.
*
* Written by L.Vanhelsuwé © 1990
*
* - started/finished on 12-Mar-1990
* - quick check before releasing to Fish PD 22-May-1994
*********************************************************************/
#include <exec/types.h>
#include <intuition/intuition.h>
#include <clib/exec_protos.h> // ANSI function prototypes
#include <clib/alib_protos.h>
#include <clib/dos_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#define FIRST_ARG argv[1]
#define LF (0x0a)
#define MAX_COLOR 16 /** IN HIRES SCREEN **/
#define COLOR 15 /** MASK FOR HARDWARE COLOR PRIMARY **/
#define CHUNK_ID long
#define CHUNK_LEN long
#define COLORS 16
#define NEXT_COLOR ' '
#define PREV_COLOR '\b'
#define NEXT_PICTURE 'n'
#define PREV_PICTURE 'p'
#define QUIT 'q'
#define IN 1 /** COLOR FADE DIRECTIONS **/
#define OUT 0
#define MAX_ALLOCS 40 // maximum objects allocated
/************************************************************************/
char ver[] = "$VER: EDUSHOW v0.9 (12-MAR-90) by Laurence Vanhelsuwé";
char screentitle[] =
"WICPUG 68000 Assembly Language Course -Educational Slideshow 0.9 (C) LVA 1990";
int count_lines(char *text); /** AND ZERO TERMINATE LINES !! **/
int cache_all_pictures(char * list_of_pictures, int number_of_pics);
/****** non "int" functions ******/
char * load_file(char *name); /** CACHES ANY FILE IN MEMORY **/
char * next_string(char*n); /** NEXT START OF LINE **/
char * expand_line(char*a,char*b); /** UN-COMPRESS RUN-LENGTH LINE **/
char * find_chunk(char*s,char*n); /** FIND START OF ANY iff CHUNK **/
char get_input(void); /** USER INPUT ROUTINE **/
short scale_color(short,short); /** FADE COLOR n BY FACTOR x **/
void fade_color(int p, int d); /** FADES PEN n IN or OUT **/
void fade_screen(int dir);
void decode_color_maps(struct mem_iff_pic *mip_array,int n); /** UNPACKS iff CMAP INTO INTERNAL FORM **/
void decompress_pic(void); /** PUT COMPRESSED PICTURE ON SCREEN **/
void open_screen(void); /** OPEN AN Intuition SCREEN **/
void lights_out(void); /** ALL PENS ARE SET TO BLACK **/
void close_everything(void); /** DEALLOCATE,FREE,CLOSE ALL **/
void next_color(void); /** FADE IN NEXT COLOR IN SLIDE **/
void prev_color(void); /** FADE OUT CURRENT COLOR IN SLIDE **/
void next_picture(void); /** FADE OUT THIS SLIDE, SHOW NEXT **/
void prev_picture(void); /** FADE OUT THIS SLIDE, SHOW PREV **/
struct Screen * OpenScreen();
struct Window * OpenWindow();
/****** global variables ******/
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Screen *screen;
struct Window *window;
struct ViewPort *vport;
int current_pic,current_color,lessons;
int alloc_num=0;
/****** global structures *****/
struct iff_header { /** THIS DEFINES THE iff HEADER **/
CHUNK_ID form_id;
CHUNK_LEN form_len;
CHUNK_ID form_type;
CHUNK_ID bmhdr_id;
CHUNK_LEN bmhdr_len;
short width;
short height;
long unknown;
BYTE planes;
BYTE pad0;
BYTE compression;
BYTE pad1;
long pad2,pad3;
CHUNK_ID cmap_id;
CHUNK_LEN cmap_len;
char cmap[16*3];
CHUNK_ID body_id;
CHUNK_LEN body_len;
char body;
};
struct mem_iff_pic {
struct iff_header *file_buffer; /** PTR TO COMPRESSED IFF PIC **/
char *body_ptr; /** PTR TO BODY CHUNK IFF **/
short cmap [COLORS][3]; /** EXPANDED COLOR PALETTE */
};
struct mem_iff_pic *lesson_pics;
struct mem_block { /** define a struct for every object **/
char *ptr; /** that we've allocated **/
int size;
} allocations[MAX_ALLOCS];
/*************************************************************************/
/*************************** START OF MAIN *******************************/
/*************************************************************************/
main(argc,argv) /** TAKES A SCRIPT FILE AS ARGUMENT **/
int argc;
char *argv[];
{
char *script_buffer;
char user_input;
int script_size;
int success;
script_size = 0;
// printf("Filename = %s # of args = %d\n",FIRST_ARG,argc);
if (argc != 2) exit (100);
printf("EDUcational slideSHOW V0.9 (C) 1990 L. Vanhelsuwé\n");
printf("-------------------------- -------------------------\n");
printf("\n");
printf("Use the following keys to control the presentation:\n");
printf("\n");
printf("SPACE...... fade in next image element\n");
printf("BACKSPACE.. fade out current image element\n");
printf("'N'........ fade in next slide\n");
printf("'P'........ fade in previous slide\n\n");
printf("'Q'........ to quit\n\n");
printf("HIT <ENTER> to start presentation."); getch();
printf("\n");
GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0);
IntuitionBase = (struct IntuitionBase*) OpenLibrary("intuition.library",0);
script_buffer = load_file(FIRST_ARG); /** LOAD SCRIPT **/
if (script_buffer == NULL) exit(100);
lessons = count_lines(script_buffer); /** HOWMANY PICS **/
printf("Number of Slides in this presentation = %d \n",lessons);
lesson_pics = (struct mem_iff_pic*)
AllocMem(lessons*sizeof (struct mem_iff_pic),0);
/** LOAD ALL PICS **/
success = cache_all_pictures(script_buffer,lessons);
if (success == FALSE)
{
printf("Cache technique failed this time....\n");
exit(100);
}
decode_color_maps(lesson_pics,lessons);
open_screen(); /** OPEN SLIDESHOW SCREEN **/
current_pic = -1; /** START SHOW OFF .... **/
next_picture();
while ( (user_input = get_input()) != QUIT)
{
switch (user_input)
{
case 13:
case NEXT_COLOR: next_color(); break;
case PREV_COLOR: prev_color(); break;
case NEXT_PICTURE: next_picture(); break;
case PREV_PICTURE: prev_picture(); break;
default:
printf("Don't know event %d !\n",(int) user_input);
}
}
close_everything(); /** RELEASE SCREEN,CACHE ETC..**/
CloseLibrary((struct Library*)GfxBase);
CloseLibrary((struct Library*)IntuitionBase);
printf ("\n\nHave a nice day..\n");
}
/***********************************************************************/
// Turn screen dark, decompress next slide, fade it in.
/***********************************************************************/
void next_picture()
{
if (current_pic != (lessons -1) )
{
lights_out();
current_pic++;
decompress_pic();
current_color = 1; fade_color(current_color,IN);
}
}
/***********************************************************************/
// Fade next "subject" in (mapped to a unique pen color)
// Goto next slide if no more subjects.
/***********************************************************************/
void next_color()
{
current_color++;
if (current_color < MAX_COLOR)
{
fade_color(current_color,IN);
}
else
{
next_picture();
}
}
/***********************************************************************/
// Do opposite of next_color()
/***********************************************************************/
void prev_color()
{
if (current_color != 1)
{
fade_color( current_color, OUT );
current_color--;
}
else
{
prev_picture();
}
}
/***********************************************************************/
// Backtrack by going back to previous slide
/***********************************************************************/
void prev_picture()
{
if (current_pic != 0)
{
lights_out();
current_pic--;
decompress_pic();
fade_screen(IN);
current_color = 1;
}
}
/***********************************************************************/
char get_input() /** WAIT FOR ANY ASCII KEY PRESS **/
{
int type = -1;
char key;
struct IntuiMessage * msg;
while (type != VANILLAKEY)
{
Wait(1 << window->UserPort->mp_SigBit);
while (msg = (struct IntuiMessage *) GetMsg(window->UserPort))
{
type = msg->Class;
key = (char) msg->Code;
ReplyMsg((struct Message*)msg);
}
}
return key;
}
/***********************************************************************/
// Cache a picture file in its entirety.
/***********************************************************************/
char * load_file(name)
char * name;
{
int file_handle;
int file_size;
char * buff_ptr;
file_handle = Open(name,MODE_OLDFILE);
if (file_handle) {
Seek(file_handle,0L,OFFSET_END);
file_size = Seek(file_handle,0L,OFFSET_BEGINNING);
buff_ptr = (char *) AllocMem(file_size +1,0); /* ANY MEM */
if (buff_ptr == NULL)
return NULL; /* ALLOC FAILED */
allocations[alloc_num].ptr = buff_ptr; // Track allocations
allocations[alloc_num].size = file_size+1;
alloc_num++;
Read(file_handle,buff_ptr,file_size);
Close(file_handle);
*(buff_ptr+file_size) = '\0'; /** ADD END TAG **/
return buff_ptr;
} else {
printf("OPEN FAILED : file %s \n",name);
exit(100);
}
}
/***********************************************************************/
// Go through script counting # of lines (== number of slides)
/***********************************************************************/
int count_lines(text) /** AND ZERO TERMINATE LINES !! **/
char * text;
{
int lines=0;
register char *text_ptr=text;
register char ch;
while (ch = *text_ptr++) /** UNTIL WE HIT END OF TEXT **/
{
if (ch == LF) /** COUNT LINE FEEDS **/
{
lines++;
*(text_ptr-1) = '\0'; /* CHANGE INTO C-STRING **/
}
}
return lines;
}
/***********************************************************************/
int cache_all_pictures(list_of_pictures,number_of_pics)
char * list_of_pictures;
int number_of_pics;
{
int i;
struct mem_iff_pic *mip;
char *ptr, *fname = list_of_pictures;
mip = lesson_pics;
for (i=0; i<number_of_pics; i++,mip++) {
// printf("FNAME #%d -> %s \n",i,fname);
mip->file_buffer = (struct iff_header *) load_file(fname);
// printf("Mmmmm... cached at %x \n", (int) mip->file_buffer);
if (mip->file_buffer == NULL) {
printf("Madonna !*$% NO MORE MEMORY !\n");
return FALSE;
}
ptr = (char *) &mip->file_buffer->bmhdr_id;
mip->body_ptr = find_chunk(ptr,"BODY");
fname = next_string(fname);
}
return TRUE;
}
/***********************************************************************/
char * next_string(text)
char * text;
{
register char *ptr=text;
while (*ptr++)
;
return ptr;
}
/***********************************************************************/
char * find_chunk(start,name)
char *start,*name;
{
long *len;
while ( (start[0] != name[0]) || (start[1] != name[1]) ||
(start[2] != name[2]) || (start[3] != name[3]) )
{
len = (long *) start +1;
start += (*len)+8;
}
return start+8;
}
/***********************************************************************/
void decode_color_maps(mip_array,entries)
struct mem_iff_pic *mip_array;
int entries;
{
int c,i;
struct mem_iff_pic *mip=mip_array;
struct iff_header *ptr;
char *gun_ptr;
for(i=0; i<entries; i++) {
ptr = (struct iff_header*) mip->file_buffer;
// printf("Planes = %d ",(int) ptr->planes);
// printf("Width = %d Height = %d ",
// (int) ptr->width, (int) ptr->height);
// printf("Compressed = %s",ptr->compression?"YES":"NO");
// printf("\n");
gun_ptr = &ptr->cmap[0];
for(c=0; c<16; c++)
{
mip->cmap[c][0] = (short) (*(gun_ptr++)>>4) &COLOR;
mip->cmap[c][1] = (short) (*(gun_ptr++)>>4) &COLOR;
mip->cmap[c][2] = (short) (*(gun_ptr++)>>4) &COLOR;
}
mip++;
}
}
/***********************************************************************/
void lights_out()
{
int color;
for (color=0; color<16; color++)
{
SetRGB4(vport,color,0,0,0);
}
}
/***********************************************************************/
// Fade a CLUT from dark to normal or vice versa.
/***********************************************************************/
void fade_screen(direction)
int direction;
{
short i,pen,min,max,incr;
short red,green,blue;
struct mem_iff_pic *mip;
mip = lesson_pics + current_pic;
if (direction == IN) {
min = 0; max = MAX_COLOR; incr = 1;
} else {
min = MAX_COLOR; max = 0; incr = -1;
}
for (i=min; i != max ; i = i+incr) /** INTENSITY 0..16 **/
{
for (pen=0; pen < MAX_COLOR; pen++) /** PEN 0..15 **/
{
red = scale_color(mip->cmap[pen][0],i);
green = scale_color(mip->cmap[pen][1],i);
blue = scale_color(mip->cmap[pen][2],i);
SetRGB4(vport,pen,red,green,blue);
}
Delay(1);
}
}
/***********************************************************************/
// Core routine for fade: "scale" an RGB triplet by a brightness factor.
/***********************************************************************/
void fade_color(pen,direction)
int pen,direction;
{
short i,min,max,incr;
short red,green,blue;
struct mem_iff_pic *mip;
mip = lesson_pics + current_pic;
if (direction == IN) {
min = 0; max = MAX_COLOR; incr = 1;
} else {
min = MAX_COLOR; max = 0; incr = -1;
}
for (i=min; i != max ; i = i+incr) {
red = scale_color(mip->cmap[pen][0],i);
green = scale_color(mip->cmap[pen][1],i);
blue = scale_color(mip->cmap[pen][2],i);
SetRGB4(vport,pen,red,green,blue);
Delay(1);
}
}
/***********************************************************************/
short int scale_color(primary,intens)
short primary;
short intens;
{
primary = (primary*intens)>>4;
return primary;
}
/***********************************************************************/
// Expand cached IFF picture to currently darkened screen.
/***********************************************************************/
void decompress_pic()
{
short scan_line; /** SCREEN LINE COUNTER **/
char *p1,*p2,*p3,*p4,*data; /** PTRS TO IFF & PLANES **/
struct mem_iff_pic *mip; /** PTR TO PICTURE DESCRIPTOR **/
mip = lesson_pics + current_pic;
data = mip->body_ptr;
p1 = screen->BitMap.Planes[0]; /** FIND BITPLANES OF SCREEN **/
p2 = screen->BitMap.Planes[1];
p3 = screen->BitMap.Planes[2];
p4 = screen->BitMap.Planes[3];
for(scan_line=0; scan_line<200; scan_line++) {
data = expand_line(data,p1); /** DECODE ONE LINE PER */
data = expand_line(data,p2); /** PLANE AT A TIME */
data = expand_line(data,p3);
data = expand_line(data,p4);
p1 += 80; p2 += 80; p3 += 80; p4 += 80; /** NEXT LINE.. **/
}
}
/***********************************************************************/
char * expand_line(data,plane_ptr) /** RUN-LENGTH DECOMPRESSOR **/
char *data,*plane_ptr;
{
char code,pattern,*eol;
eol = plane_ptr +80; /** CALC END OF LINE **/
while (plane_ptr != eol) {
code = *data++; /** GET ENCRYPTION TYPE && 'N' **/
if (code < 0) /** NEGATIVE : REPLICATE NEXT BYTE **/
{
code = (-code) +1;
pattern = *data++;
while (code--)
{
*plane_ptr++ = pattern;
}
} else { /** POSITIVE : COPY LITERAL RUN **/
code++;
while (code--)
{
*plane_ptr++ = *data++;
}
}
}
return data; /** RETURN UPDATED SOURCE PTR **/
}
/***********************************************************************/
void open_screen() {
static struct NewScreen myscreen = /** INTUITION SCREEN **/
{ /** PARAMETER BLOCK **/
0,0,
640,200,
4,
1,0,
HIRES,
CUSTOMSCREEN,
NULL,screentitle,
NULL,NULL
};
struct NewWindow mywindow = /** INTUITION WINDOW **/
{ /** PARAMETER BLOCK **/
0,0,
640,200,
255,255,
VANILLAKEY, /** WANT KEY PRESSES **/
BACKDROP+ACTIVATE,
NULL,NULL,
NULL, /* NO TITLE */
NULL,NULL,
0,0,640,200,
CUSTOMSCREEN
};
screen = OpenScreen(&myscreen); /** MAGIC ! **/
if (screen == NULL) {
printf("Damn You : NO SCREEN !\n");
exit(100);
}
vport = &screen->ViewPort; /** HANDLE FOR COLOR CHANGES **/
mywindow.Screen = screen;
window = OpenWindow(&mywindow);
}
/***********************************************************************/
void close_everything()
{
int i;
CloseWindow(window);
CloseScreen(screen);
for (i=0; i< alloc_num; i++) {
FreeMem(allocations[i].ptr, allocations[i].size);
}
FreeMem((char*) lesson_pics, lessons * sizeof(struct mem_iff_pic));
/* return cached file buffers & descriptor array */
}
/***********************************************************************/